package org.framework.common.ext.util;

import java.math.BigDecimal;
import java.util.Date;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.framework.common.api.query.Criterion.ValueType;
import org.framework.common.api.support.constant.SystemConstants;
import org.framework.common.ext.exception.CommonException;

import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;

/**
 * 字符串工具类.
 * <p>描述:</p>
 * <p>Company:上海中信信息发展股份有限公司</p>
 * @author chanlong(陈龙)
 * @date 2014年2月26日  上午9:18:47
 * @version 1.0.2014.
 */
public class StringUtil {

	public static final int ASPECT_PREFIX = 0x1;
	public static final int ASPECT_SUFFIX = 0x0;
	public static final String DEFAULT_PASSWORD = "000000";
	
	/**
	 * 中文转拼音.
	 * @param orig
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2016年8月5日 下午12:23:05
	 */
	public static String toPinyin(final String orig){
		HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
		format.setCaseType(HanyuPinyinCaseType.LOWERCASE);
		format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
		format.setVCharType(HanyuPinyinVCharType.WITH_V);
		
		char[] chs = orig.toCharArray();
		StringBuilder res = new StringBuilder();
		try {
			for (char ch : chs) {
				String[] temps = PinyinHelper.toHanyuPinyinStringArray(ch, format);
				res.append(temps[0]);
			}
		} catch (BadHanyuPinyinOutputFormatCombination e) {
			return orig;
		} catch (NullPointerException e) {
			return orig;
		}
		return res.toString();
	}
	
	/**
	 * 数字补零.
	 * @param number
	 * @param aspect
	 * @param length
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2016年1月23日 下午4:57:30
	 */
	public static String zeroize(final int number, final int aspect, final int length){
		return zeroize(String.valueOf(number), aspect, length);
	}
	
	/**
	 * 数字补零.
	 * @param number
	 * @param aspect
	 * @param length
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2016年1月23日 下午4:58:18
	 */
	public static String zeroize(final String number, final int aspect, final int length){
		String zero = "";
		for(int i = number.length(); i < length; i++){
			zero+="0";
		}
		switch(aspect){
			case ASPECT_PREFIX: return zero+number;
			case ASPECT_SUFFIX: return number+zero;
			default: return String.valueOf(number);
		}
	}
	
	/**
	 * 判断对象是否为空.
	 * @param value
	 * @return
	 * @author Administrator(陈龙)
	 * @date 2014-1-17  上午10:35:31
	 */
	public static boolean isEmpty(final Object value){
		try{
			return StringUtils.isEmpty(value.toString()) || "null".equals(value) || "[]".equals(value);
		}catch(NullPointerException e){
			return true;
		}
	}
	
	/**
	 * 判断对象是否为空.
	 * @param value
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2015年12月28日 上午11:08:48
	 */
	public static boolean isNotEmpty(final Object value){
		try{
			return StringUtils.isNotEmpty(value.toString()) && !"null".equals(value) && !"[]".equals(value);
		}catch(NullPointerException e){
			return false;
		}
	}
	
	/**
	 * 去除字符串中的换行、回车.
	 * @param value
	 * @return
	 * @author Administrator(陈龙)
	 * @date 2014-1-17  上午10:36:15
	 */
	public static String nowrap(final String value){
		try {
			return replaceAll(value,"\t|\r|\n","");
		} catch (Exception e) {
			return "";
		}
	}	

	/**
	 * 基于正则表达式截取字符串.
	 * @param value
	 * @param regex
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2014年8月3日  下午6:13:06
	 */
	public static String substr(final String value, final String regex){
		String returnstr = null;
		
		if(!isEmpty(value)){
			Pattern pattern = Pattern.compile(regex);
			Matcher matcher = pattern.matcher(value);
			while(matcher.find()) returnstr = matcher.group(1);
		}
		
		return returnstr;
	}

	/**
	 * 基于正则表达式替换字符串.
	 * @param value
	 * @param regex
	 * @param replacements
	 * @return
	 * @author chanlong(陈龙)
	 * @throws CommonException 
	 * @date 2014年6月16日  下午3:57:07
	 */
	public static String replaceAll(final String value, final String regex, final String... replacements) throws Exception{
		String returnstr = value;
		try {
			Pattern pattern = Pattern.compile(regex);
			if(replacements.length == 1){
				Matcher matcher = pattern.matcher(returnstr);
				returnstr = matcher.replaceAll(replacements[0]);
			}else{
				for (String replacement : replacements) {
					Matcher matcher = pattern.matcher(returnstr);
					returnstr = matcher.replaceFirst(replacement);
				}
			}
		} catch (IndexOutOfBoundsException e) {
			throw new Exception("要替换的操作数与正则表示不一致", e);
		}
		return returnstr;
	}
	
	/**
	 * 字符串转数组.
	 * @param value
	 * @param regex
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2014年3月3日  上午11:13:21
	 */
	public static String[] toArray(final String value, final String regex) {
		try {
			return value.split(regex);
		} catch (NullPointerException e) {
			return new String[] { "" };
		}
	}
	
	/**
	 * 数组转SQL字串.
	 * @param value
	 * @param regex
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2016年7月20日 下午5:33:19
	 */
	public static String toSQLEscape(final Object value) {
		try {
			StringBuilder strb = new StringBuilder();
			
			if(value instanceof Object[]){
				Object[] values = (Object[])value;
				for (int i = 0; i < values.length; i++) {
					strb.append("'").append(values[i]).append("'");
					
					if(i < values.length-1){ strb.append(","); }
				}
			}else{
				return null;
			}
			
			return strb.toString();
		} catch (NullPointerException e) {
			e.printStackTrace();
			return null;
		}
	}
	
	/**
	 * 数组转SQL字串.
	 * @param value
	 * @param regex
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2016年7月20日 下午5:33:19
	 */
	public static String toSQLEscape(final Object value, final String regex) {
		try {
			StringBuilder strb = new StringBuilder();
			
			if(value instanceof Object[]){
				Object[] values = (Object[])value;
				for (int i = 0; i < values.length; i++) {
					strb.append(values[i]);
					
					if(i < values.length-1){ strb.append("'").append(regex).append("'"); }
				}
			}else{
				return null;
			}
			
			return strb.toString();
		} catch (NullPointerException e) {
			e.printStackTrace();
			return null;
		}
	}
	
	/**
	 * .
	 * @param value
	 * @param integers
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2016年8月11日 上午10:02:25
	 */
	@SuppressWarnings("unchecked")
	public static <T> T[] parseValue(final Object value, final ValueType integers, final T t) {
		if(StringUtil.isNotEmpty(value)){
			String[] values = String.valueOf(value).split(SystemConstants.SYMBOL_COMMA);
			switch (integers) {
				case FLOATS:{
					Float[] returnValue = new Float[values.length]; 
					for (int i = 0; i < values.length; i++) {
						returnValue[i] = Float.valueOf(values[i]);
					}
					return (T[])returnValue;
				}
				case INTEGERS:{
					Integer[] returnValue = new Integer[values.length]; 
					for (int i = 0; i < values.length; i++) {
						returnValue[i] = Integer.valueOf(values[i]);
					}
					return (T[])returnValue;
				}
				default: return (T[])values;
			}
		}
		return (T[])value;
	}
	
	/**
	 * 为了SQL过滤字符串，转义其中的反斜杠\，百分号%，下划线_，单引号'.
	 * @param str
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2014年5月3日  上午3:48:15
	 */
	public static String escapeString4Sql(final String str) {
		String result = "";
		if (isNotEmpty(str)) {
			result = str.replaceAll("\\\\", "\\\\\\\\")
						.replaceAll("%", "\\\\%")
						.replaceAll("_", "\\\\_")
						.replaceAll("'", "''");
		}
		return result;
	}
	
	/**
	 * MD5加密.
	 * @param text
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2014年5月7日  下午9:38:09
	 */
	public static String md5(final String text) {
		String result = null;
		try {
			if (isNotEmpty(text)) {
				result = DigestUtils.md5Hex(text);
			}
		} catch (Exception e) {
			result = "";
		}
		return result;
	}
	
	/**
	 * 获取指定密码的MD5值.
	 * @param password
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2016年4月12日 下午12:16:19
	 */
	public static String password(final String password){
		return md5(password);
	}
	
	/**
	 * 生成UUID.
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2016年8月5日 下午12:22:13
	 */
	public static String uuid(){
		String[] uuids = UUIDUtils.create().toString().split("-");
		return new StringBuilder(uuids[1]).append(uuids[2]).append(uuids[3]).append(uuids[4]).append(uuids[0]).toString();
	}
	
	/**
	 * 获取参数.
	 * @param value
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2016年8月5日 下午12:22:31
	 */
	public static Object getPramameter(Object value) {
		return isNotEmpty(value) ? value : null;
	}
	
	/**
	 * 生成订单编号.
	 * @param prefix
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2016年6月5日 下午4:38:53
	 */
	public static String orderno(String suffix){
		return new StringBuilder(DateFormatUtils.format(new Date(), "yyyyMMdd")).append(System.currentTimeMillis()).append(suffix).toString();
	}
	
	/**
	 * 随机短信.
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2016年8月19日 上午11:40:27
	 */
	public static String smscode() {
		Random rnd = new Random();
		int num = rnd.nextInt(8999) + 1000;
		return String.valueOf(num);
	}
    
	/**
	 * 四舍五入除法.
	 * @param n1
	 * @param n2
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2016年9月20日 下午1:16:27
	 */
	public static Float round(final float n1, final float n2, int scale) {
		BigDecimal b1 = new BigDecimal(n1);
		BigDecimal b2 = new BigDecimal(n2);
		return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).floatValue();
	}
	
    public static void main(String[] args) {
		try {
			System.out.println(replaceAll("请上传像素为（? x ?）的图片", "\\?", "91","90"));
			
			System.out.println(toPinyin("哈雅宝贝早教中心"));
			
			System.out.println(orderno("4028b881547a3beb01547a469d420001"));

			System.out.println(uuid());
			
			System.out.println(round(1, 60, 2));
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
